home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2010 Summer - Disc 1 / WN_Ete2010_CD1.iso / Onglet5 / Weezo / Weezo setup.exe / {code_appDir} / www / includes / fileInfoFunctions.php < prev    next >
PHP Script  |  2010-05-19  |  33KB  |  930 lines

  1. <?php
  2. /**
  3.  * Get detailled file information
  4.  *
  5.  * PHP version 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   NA
  14.  * @package    NA
  15.  * @author     Nicolas Bruley / Peer 2 World <contact@weezo.net>
  16.  * @copyright  2005-2009 Nicolas Bruley / Peer 2 World
  17.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18.  * @version    CVS: $Id:$
  19.  * @link       http://www.weezo.net
  20.  * @since      File available since Release 1.1.1
  21.  */
  22.  
  23. require_once(INCLUDE_DIR.'mime_type.php');
  24.  
  25. $_ENV['thumbnailMaxWidth']=(cfRGetVar('tooltipImageWidth'))?cfRGetVar('tooltipImageWidth'):160;
  26. $_ENV['thumbnailMaxHeight']=(cfRGetVar('tooltipImageHeight'))?cfRGetVar('tooltipImageHeight'):120;
  27.  
  28.  
  29. /**
  30.  * @desc Parse playlist: return a PHP array from a playlist
  31.  *
  32.  * @param string $completeFilename: path to playlist, or single audio file
  33.  * @param boolean $allowedFilesOnly: include only existing and downloadable files
  34.  * @param boolean $getProperties: get audio files properties
  35.  * @return array(0 => completeFilename, 1 => ...) path and filename of found songs
  36.  */
  37. function fiParsePlaylistFile($completeFilename, $allowedFilesOnly=false, $getProperties=false){
  38.     $songs=array();
  39.     $path=cfDirName($completeFilename); if(substr($path,-1)!='/') $path.='/';
  40.  
  41.     // Dynamic playlist
  42.     if($completeFilename=='*playlist*.m3u'){
  43.         if(cfRGetVar('shufflePlaylist')) $playlist=cfRGetVar('playlistShuffled');
  44.         else $playlist=cfRGetVar('playlist');
  45.  
  46.         foreach ($playlist as $v) $songs[]['cfn']=$v['completeFileName'];
  47.     }
  48.  
  49.     // Read M3U playlist file
  50.     else switch (cfFileExtension($completeFilename)){
  51.         // M3U
  52.         case 'm3u':
  53.         // Open playlist
  54.         if(!file_exists($completeFilename) || (!$handle = fopen ($completeFilename, "r"))) return array();
  55.         while (!feof ($handle)) {
  56.             $line=trim(fgets($handle, 4096));
  57.             if($line && substr($line,0,1)!='#'){
  58.                 if(substr($line,1,1)!=':') $line=cfJoinPathFile($path,$line);
  59.                 if(!$allowedFilesOnly) $songs[]['cfn']=$line;
  60.                 elseif (file_exists($line) && cfFileRights($line,'download')) $songs[]['cfn']=$line;
  61.             }
  62.         }
  63.         fclose($handle);
  64.         break;
  65.  
  66.         // Winamp PLS
  67.         case 'pls':
  68.         // Open playlist
  69.         if(!file_exists($completeFilename) || (!$handle = fopen ($completeFilename, "r"))) return array();
  70.         while (!feof ($handle)) {
  71.             $line=trim(fgets($handle, 4096));
  72.             if(substr($line,0,4)=='File' && strpos($line,'=')){
  73.                 $line=substr($line,strpos($line,'=')+1);
  74.                 if(substr($line,1,1)!=':') $line=cfJoinPathFile($path,$line);
  75.                 if(!$allowedFilesOnly) $songs[]['cfn']=$line;
  76.                 elseif (file_exists($line) && cfFileRights($line,'download')) $songs[]['cfn']=$line;
  77.             }
  78.         }
  79.         fclose($handle);
  80.         break;
  81.         default:
  82.             require_once('explorerFunctions.php');
  83.             if(strpos($completeFilename,'*resSpecific*')!==false && cfRGetVar('extAccessFunction')) {
  84.                 $extAccessFunction = create_function('$completeFilename', cfRGetVar('extAccessFunction'));
  85.                 if(!($cfn=$extAccessFunction($completeFilename))) return array();
  86.                 $songs[]=array('cfn'=>$cfn,'efn'=>$completeFilename);
  87.             }
  88.             else{
  89.                 if(efFileType($completeFilename)!='audio' && efFileType($completeFilename)!='video') return array();
  90.                 if(!$allowedFilesOnly) $songs[]['cfn']=$completeFilename;
  91.                 elseif (file_exists($completeFilename) && cfFileRights($completeFilename,'download')) $songs[]['cfn']=$completeFilename;
  92.             }
  93.     }
  94.  
  95.     // Get songs properties for embeded tags
  96.     if($getProperties){
  97.         require_once('explorerFunctions.php');
  98.         foreach ($songs as $k=>$v){
  99.             $songs[$k]['ai']=efGetAudioInfo($v['cfn'],true);
  100.         }
  101.     }
  102.     return $songs;
  103. }
  104.  
  105. /**
  106.  * @desc Convert an array generated by fiParsePlaylistFile to a playlist file
  107.  *
  108.  * @param string $playlist: playlist array: ('cfn'=>completeFilename, 'ai'=>array(audio info, see efGetAudioInfo()))
  109.  * @param string $playlistFormat: 'm3u','asx','pls','asx','xml'
  110.  * @param array $encodingOptions: reencoding options
  111.  *             ('outputBitrate' for audio reencoding, 'w','h','q','offset' for video, 'URI' to use URI passed into 'fileLink' key of $v)
  112.  * @param string $addressMode: 'relative' | 'absolute'
  113.  * @param boolean $preUTF8Encode
  114.  * @return unknown
  115.  */
  116. function fiArrayToPlaylist($playlist, $playlistFormat, $encodingOptions, $addressMode="relative", $preUTF8Encode=true){
  117.     function fileLink($v, $encodingOptions, $addressMode, $preUTF8Encode){
  118.         $cfn=$v['cfn'];    $efn=(isset($v['efn']))?$v['efn']:$cfn;
  119.         // Passed URI
  120.         if($encodingOptions=='URI' && isset($v['uri'])) return $v['uri'];
  121.         // Audio files
  122.         if(efFileType($cfn)=='audio') return cfExtAudio($efn,((isset($encodingOptions['outputBitrate'])?"audio/".$encodingOptions['outputBitrate']."/":'')),$addressMode,$preUTF8Encode);
  123.         // Video files
  124.         return cfExtVideo($efn,$encodingOptions,$addressMode,$preUTF8Encode);
  125.     }
  126.  
  127.  
  128.     require_once(INCLUDE_DIR.'explorerFunctions.php');
  129.  
  130.     switch ($playlistFormat){
  131.         // M3U
  132.         case 'm3u':
  133.             $output="#EXTM3U\n\n";
  134.             foreach ($playlist as $v){
  135.                 $output.='#EXTINF '.((isset($v['ai']['length']))?($v['ai']['length']/1000):'-1').','.
  136.                     ((isset($v['ai']['title']))?$v['ai']['title']:cfFileWithoutExtension(basename($v['cfn'])));
  137.                 $output.="\n".fileLink($v,$encodingOptions,$addressMode,$preUTF8Encode)."\n";
  138.             }
  139.         break;
  140.  
  141.         // Winamp PLS
  142.         case 'pls':
  143.             $output="[playlist]\nNumberOfEntries=".count($playlist)."\n\n";
  144.             $i=1;
  145.             foreach ($playlist as $v){
  146.                 $output.='File'.$i.'='.fileLink($v,$encodingOptions,$addressMode,$preUTF8Encode)."\n";
  147.                 $output.='Length'.$i.'='.((isset($v['ai']['length']))?($v['ai']['length']/1000):'-1')."\n";
  148.                 $output.='Title'.$i.'='.((isset($v['ai']['title']))?$v['ai']['title']:cfFileWithoutExtension(basename($v['cfn'])))."\n\n";
  149.                 $i++;
  150.             }
  151.             $output.="\nVersion=2";
  152.         break;
  153.  
  154.         // MS WMP ASX
  155.         case 'asx':
  156.             $output="<ASX VERSION=\"3.0\">\n    <PARAM NAME=\"encoding\" VALUE=\"utf-8\" />\n    <TITLE>".cfCaption('explorerAudioPlaylist')."</TITLE>\n";
  157.  
  158.             foreach ($playlist as $v){
  159.                 $output.="    <ENTRY>\n";
  160.                 $output.='        <TITLE>'.cfUTF8Encode((isset($v['ai']['title']))?$v['ai']['title']:cfFileWithoutExtension(basename($v['cfn'])))."</TITLE>\n";
  161.                 $output.='        <REF HREF="'.fileLink($v,$encodingOptions,$addressMode,$preUTF8Encode).'" />';
  162.                 if(isset($v['ai']['length'])) $output.="\n        <DURATION VALUE=\"".(floor($v['ai']['length']/1000)).'" />';
  163.                 $output.="\n    </ENTRY>\n";
  164.             }
  165.             $output.="</ASX>";
  166.  
  167.         break;
  168.  
  169.         // Internal XML format, used by audio flash player
  170.         case 'xml':
  171.             $output='<?xml version="1.0" encoding="utf-8"?>'."\n".'<playlist volume="'.((cfUGetVar('audioVolume')!==false)?cfUGetVar('audioVolume'):'80').'">'."\n";
  172.             foreach ($playlist as $v){
  173.                 $file=cfXMLEncodeProperty(fileLink($v,$encodingOptions,$addressMode,$preUTF8Encode));
  174.                 $output.='<audio externalRef="'.$file.'" songLabel="'.((isset($v['ai']['label']))?cfXMLEncodeProperty(cfUTF8Encode($v['ai']['label'])):'').'" file="'.$file."\" />\n";
  175.  
  176.             }
  177.             $output.='</playlist>';
  178.  
  179.         break;
  180.         default:
  181.             throw new Exception('Unsupported output playlist format');
  182.             return;
  183.     }
  184.  
  185.     return $output;
  186. }
  187.  
  188. /**
  189.  * @desc Convert a PHP associative array to string definition of JS associative array
  190.  *
  191.  * @param array $inArray
  192.  * @return string
  193.  */
  194. function fiPHPArrayToJSArray($inArray){
  195.     $out='';
  196.     if(!is_array($inArray)) return '{}';
  197.     foreach($inArray as $k=>$v) {
  198.         // HTML code, do not protect
  199.         if($k=='vhtml') $k='v';
  200.         elseif($k=='chtml') $k='c';
  201.         elseif(!is_array($v) && substr($v,0,5)!='code:') $v=str_replace('<','<',$v);
  202.  
  203.         // Key
  204.         $out.=",'".addcslashes($k,'"\'')."':";
  205.  
  206.         // Array
  207.         if(is_array($v)) $out.=fiPHPArrayToJSArray($v);
  208.         // Else: protect string
  209.         else{
  210.             $l=strlen($v);
  211.             for ($i=0;$i<$l;$i++) if(ord(substr($v,$i,1))<32) $v[$i]=' ';
  212.  
  213.             // Caption: don't utf-8 encode
  214.             if($k=='c') $out.="'".addcslashes($v,'"\'\\')."'";
  215.  
  216.             // other value
  217.             else $out.="'".addcslashes(cfUTF8Encode($v,false,false),'"\'\\')."'";
  218.         }
  219.  
  220.     }
  221.     return '{'.substr($out,1).'}';
  222. }
  223.  
  224. /**
  225.  * @desc Create an array with processed exif data, false if no exif data
  226.  *
  227.  * @param string $completeFilename: jpg or tiff filename
  228.  * @return array
  229.  */
  230. function mExifArray($completeFilename){
  231.     $ext=cfFileExtension($completeFilename);
  232.     if($ext!='jpg' && $ext!='jpeg' && $ext!='tiff') return false;
  233.     if(!($raw=@exif_read_data($completeFilename))) return false;
  234.  
  235.     // Discarded tags
  236.     $discarded=array('FileName','FileDateTime','FileSize','MimeType','SectionsFound','FileType','DateTime','InteroperabilityOffset');
  237.  
  238.     // Transformed tags
  239.     $transformedTags=array(
  240.         'Flash'=>array(
  241.             '0' => 'No Flash',
  242.             '1' => 'Fired',
  243.             '5' => 'Fired, Return not detected',
  244.             '7' => 'Fired, Return detected',
  245.             '8' => 'On, Did not fire',
  246.             '9' => 'On',
  247.             'd' => 'On, Return not detected',
  248.             'f' => 'On, Return detected',
  249.             '10' => 'Off',
  250.             '14' => 'Off, Did not fire, Return not detected',
  251.             '18' => 'Auto, Did not fire',
  252.             '19' => 'Auto, Fired',
  253.             '1d' => 'Auto, Fired, Return not detected',
  254.             '1f' => 'Auto, Fired, Return detected',
  255.             '20' => 'No flash function',
  256.             '30' => 'Off, No flash function',
  257.             '41' => 'Fired, Red-eye reduction',
  258.             '45' => 'Fired, Red-eye reduction, Return not detected',
  259.             '47' => 'Fired, Red-eye reduction, Return detected',
  260.             '49' => 'On, Red-eye reduction',
  261.             '4d' => 'On, Red-eye reduction, Return not detected',
  262.             '4f' => 'On, Red-eye reduction, Return detected',
  263.             '50' => 'Off, Red-eye reduction',
  264.             '58' => 'Auto, Did not fire, Red-eye reduction',
  265.             '59' => 'Auto, Fired, Red-eye reduction',
  266.             '5d' => 'Auto, Fired, Red-eye reduction, Return not detected',
  267.             '5f' => 'Auto, Fired, Red-eye reduction, Return detected'),
  268.         'SceneType'=>array(
  269.             1 => 'Directly photographed'),
  270.         'FileSource'=>array(
  271.             1 => 'Film Scanner',
  272.             2 => 'Reflection Print Scanner',
  273.             3 => 'Digital Camera'),
  274.         'ExposureMode'=>array(
  275.             0 => 'Auto',
  276.             1 => 'Manual',
  277.             2 => 'Auto bracket'),
  278.         'SensingMethod'=>array(
  279.             1 => 'Monochrome area',
  280.             2 => 'One-chip color area',
  281.             3 => 'Two-chip color area',
  282.             4 => 'Three-chip color area',
  283.             5 => 'Color sequential area',
  284.             6 => 'Monochrome linear',
  285.             7 => 'Trilinear',
  286.             8 => 'Color sequential linear'),
  287.         'PhotometricInterpretation'=>array(
  288.             0 => 'WhiteIsZero',
  289.             1 => 'BlackIsZero',
  290.             2 => 'RGB',
  291.             3 => 'RGB Palette',
  292.             4 => 'Transparency Mask',
  293.             5 => 'CMYK',
  294.             6 => 'YCbCr',
  295.             8 => 'CIELab',
  296.             9 => 'ICCLab',
  297.             10 => 'ITULab',
  298.             32803 => 'Color Filter Array',
  299.             32844 => 'Pixar LogL',
  300.             32845 => 'Pixar LogLuv',
  301.             34892 => 'Linear Raw'),
  302.         'YCbCrPositioning'=>array(
  303.             1 => 'Centered',
  304.             2 => 'Co-sited'),
  305.         'ResolutionUnit'=>array(
  306.             1 => 'None',
  307.             2 => 'Inches',
  308.             3 => 'cm'),
  309.         'FocalPlaneResolutionUnit'=>array(
  310.             1 => 'None',
  311.             2 => 'Inches',
  312.             3 => 'cm'),
  313.         'CustomRendered'=>array(
  314.             0 => 'Normal',
  315.             1 => 'Custom'),
  316.         'Predictor'=>array(
  317.             1 => 'None',
  318.             2 => 'Horizontal differencing'),
  319.         'Sharpness'=>array(
  320.             0 => 'Normal',
  321.             1 => 'Soft',
  322.             2 => 'Hard'),
  323.         'Contrast'=>array(
  324.             0 => 'Normal',
  325.             1 => 'Soft',
  326.             2 => 'Hard'),
  327.         'Saturation'=>array(
  328.             0 => 'Normal',
  329.             1 => 'Low saturation',
  330.             2 => 'High saturation'),
  331.         'ColorSpace'=>array(
  332.             1 => 'sRGB',
  333.             2 => 'Adobe RGB',
  334.             65535 => 'Uncalibrated'),
  335.         'GainControl'=>array(
  336.             0 => 'None',
  337.             1 => 'Low gain up',
  338.             2 => 'High gain up',
  339.             3 => 'Low gain down',
  340.             4 => 'High gain down'),
  341.         'SceneCaptureType'=>array(
  342.             0 => 'Standard',
  343.             1 => 'Landscape',
  344.             2 => 'Portrait',
  345.             3 => 'Night scene'),
  346.         'WhiteBalance'=>array(
  347.             0 => 'Auto white balance',
  348.             1 => 'Manual white balance'),
  349.         'MeteringMode'=>array(
  350.             0 => 'unknown',
  351.             1 => 'Average',
  352.             2 => 'CenterWeightedAverage',
  353.             3 => 'Spot',
  354.             4 => 'MultiSpot',
  355.             5 => 'Pattern',
  356.             6 => 'Partial',
  357.             255 => 'other'),
  358.         'LightSource'=>array(
  359.             0 => 'unknown',
  360.             1 => 'Daylight',
  361.             2 => 'Fluorescent',
  362.             3 => 'Tungsten (incandescent light)',
  363.             4 => 'Flash',
  364.             9 => 'Fine weather',
  365.             10 => 'Cloudy weather',
  366.             11 => 'Shade',
  367.             12 => 'Daylight fluorescent (D 5700 û 7100K)',
  368.             13 => 'Day white fluorescent (N 4600 û 5400K)',
  369.             14 => 'Cool white fluorescent (W 3900 û 4500K)',
  370.             15 => 'White fluorescent (WW 3200 û 3700K)',
  371.             17 => 'Standard light A',
  372.             18 => 'Standard light B',
  373.             19 => 'Standard light C',
  374.             20 => 'D55',
  375.             21 => 'D65',
  376.             22 => 'D75',
  377.             23 => 'D50',
  378.             24 => 'ISO studio tungsten',
  379.             255 => 'Other light source'),
  380.         'ExposureProgram'=>array(
  381.             0 => 'Not defined',
  382.             1 => 'Manual',
  383.             2 => 'Normal program',
  384.             3 => 'Aperture priority',
  385.             4 => 'Shutter priority',
  386.             5 => 'Creative program (biased toward depth of field)',
  387.             6 => 'Action program (biased toward fast shutter speed)',
  388.             7 => 'Portrait mode (for closeup photos with the background out of focus)',
  389.             8 => 'Landscape mode (for landscape photos with the background in focus)'),
  390.         'Orientation'=>array(
  391.             1 => 'Horizontal (normal)',
  392.             2 => 'Mirror horizontal',
  393.             3 => 'Rotate 180',
  394.             4 => 'Mirror vertical',
  395.             5 => 'Mirror horizontal and rotate 270 CW',
  396.             6 => 'Rotate 90 CW',
  397.             7 => 'Mirror horizontal and rotate 90 CW',
  398.             8 => 'Rotate 270 CW')
  399.         );
  400.  
  401.     $exif=array();
  402.  
  403.     // Browse properties
  404.     foreach ($raw as $tag=>$value) if(!is_array($value)) {
  405.         $discard=false;
  406.  
  407.         if(substr($tag,0,12)=='UndefinedTag') continue;
  408.  
  409.         if($tag=='FileSource') $value=ord($value);
  410.  
  411.         // Forbidden characters
  412.         for($i=0;$i<strlen($value);$i++){
  413.             if(($ord=ord(substr($value,$i,1)))<32 && $ord!=9 && $ord!=10 && $ord!=13){
  414.                 $discard=true;
  415.                 break;
  416.             }
  417.         }
  418.         if($discard) continue;
  419.  
  420.         // Discarded tags
  421.         foreach ($discarded as $k=>$d)
  422.             if($tag==$d) {$discard=true;break;}
  423.         if($discard) continue;
  424.  
  425.         // Set value
  426.         if($tag=='Flash') $value=dechex($value);
  427.         if($tag=='DateTimeOriginal' || $tag=='DateTimeDigitized') $value=date(cfCaption('_FULL_DATE_FORMAT'),strtotime($value));
  428.         if(isset($transformedTags[$tag][$value])) $exif[$tag]=$transformedTags[$tag][$value]; else $exif[$tag]=$value;
  429.     }
  430.     return $exif;
  431. }
  432.  
  433. /**
  434.  * @desc Return true if filename has detailed information (EXIF data, ...)
  435.  *
  436.  * @param string $completeFilename
  437.  * @return boolean
  438.  */
  439. function fiHasInfo($completeFilename){
  440.     $mimeType=efFileType($completeFilename);
  441.     if($mimeType=='image') return true;
  442.  
  443.     //$ext=cfFileExtension($completeFilename);
  444.     return false;
  445. }
  446.  
  447.  
  448. /**
  449.  * @desc Return flash swf specific info
  450.  *
  451.  * @param string $completeFilename: filename including path
  452.  * @param boolean $getThumbnail: true to include thumbnail
  453.  * @return array
  454.  */
  455. function fiGetInfoFolder($completeFilename,$getThumbnail){
  456.     $info=array();
  457.  
  458.     // Total contained files size
  459.     $totalSize=0;
  460.     $nbFiles=0;
  461.     $nbFolders=0;
  462.     $firstFiles=array();
  463.     $firstFolders=array();
  464.     $nbFirst=10;
  465.  
  466.     // Browse subfolders and files for total size and first elements
  467.     foreach (glob($completeFilename.'/*') as $cfn) {
  468.         if(is_file($cfn)) {
  469.             $totalSize+=cfFileSize($cfn);
  470.             $nbFiles++;
  471.             if(count($firstFiles)<$nbFirst) $firstFiles[]=basename($cfn);
  472.         }
  473.         else {
  474.             $nbFolders++;
  475.             if(count($firstFolders)<$nbFirst) $firstFolders[]=basename($cfn);
  476.         }
  477.     }
  478.  
  479.     $info['fileSize']=array('c'=>cfCaption('genSize'),'v'=>efFileSizeFormat($totalSize));
  480.  
  481.     // Icon
  482.     $info['icon']=outIcon('/fi/folder');
  483.  
  484.     // Extra data
  485.     $info['extra']['extraTitle']=array('c'=>cfCaption('explorerTotalFiles',$nbFolders,$nbFiles));
  486.     if(count($firstFiles) && count($firstFolders)) $info['extra'][0]=array('chtml'=>'<b style="padding-left:15em"> </b>','vhtml'=>'<b style="padding-left:15em"> </b>');
  487.     else $info['extra'][0]=array('c'=>' ','v'=>' ');
  488.  
  489.     // First files and folders
  490.     for($i=0;$i<$nbFirst;$i++){
  491.         if(!isset($firstFiles[$i]) && !isset($firstFolders[$i])) break;
  492.  
  493.         // Folders
  494.         if(!isset($firstFolders[$i])) $fo='';
  495.         elseif ($i==$nbFirst-1) $fo='...';
  496.         else $fo=outImage(outIcon('fi/folder'),false,false,'margin-right:0.3em',0.7).cfStrTruncate(cfUTF8Encode($firstFolders[$i]),40);
  497.  
  498.         // Files
  499.         if(!isset($firstFiles[$i])) $fi=' ';
  500.         elseif ($i==$nbFirst-1) $fi='...';
  501.         else $fi=outImage(efIcon($firstFiles[$i]),false,false,'margin-right:0.3em',0.7).cfStrTruncate($firstFiles[$i],50);
  502.  
  503.         $info['extra'][$i+1]=array('chtml'=>$fo,'vhtml'=>$fi);
  504.     }
  505.  
  506.     return $info;
  507. }
  508.  
  509. /**
  510.  * @desc Return image-specific info
  511.  *
  512.  * @param string $completeFilename: image filename
  513.  * @param boolean $getThumbnail: true to include thumbnail
  514.  * @return array
  515.  */
  516. function fiGetInfoImage($completeFilename,$getThumbnail){
  517.     $info=array();
  518.     $ext=cfFileExtension($completeFilename);
  519.  
  520.     // Image dimensions
  521.     if($ext=='itc' || $ext=='itc2'){
  522.         if(($sourceImage=@imagecreatefromstring(substr(file_get_contents($completeFilename),(($ext=='itc')?500:492))))){
  523.             $width=imagesx($sourceImage);
  524.             $height=imagesy($sourceImage);
  525.             unset($sourceImage);
  526.         }
  527.     }
  528.     if(!isset($width)) list($width, $height, $type, $attr) = @getimagesize($completeFilename);
  529.     if($width) $info['extra']['imageSize'] = array('c'=>cfCaption('genSize'), 'v'=>$width.'x'.$height.' '.cfCaption('genPixels'));
  530.     else $info['extra']['imageSize'] = array('c'=>cfCaption('genSize'), 'v'=>'? x ? '.cfCaption('genPixels'));
  531.  
  532.     // Thumbnail URL and size
  533.     if($getThumbnail && cfRGetVar('path') && $width) {
  534.         $info['thumbnailURL']=cfExtImage($completeFilename,$_ENV['thumbnailMaxWidth'],$_ENV['thumbnailMaxHeight']);
  535.         if($width && $height){
  536.             if($width/$height>$_ENV['thumbnailMaxWidth']/$_ENV['thumbnailMaxHeight'])
  537.                 {$info['thumbnailURLW']=$_ENV['thumbnailMaxWidth'];$info['thumbnailURLH']=$_ENV['thumbnailMaxWidth']*$height/$width;}
  538.             else
  539.                 {$info['thumbnailURLH']=$_ENV['thumbnailMaxHeight'];$info['thumbnailURLW']=$_ENV['thumbnailMaxHeight']*$width/$height;}
  540.         }
  541.         else{
  542.             $info['thumbnailURLW']=$_ENV['thumbnailMaxWidth'];
  543.             $info['thumbnailURLH']=$_ENV['thumbnailMaxHeight'];
  544.         }
  545.     }
  546.     // Exif data
  547.     if($ext=='jpg' || $ext=='jpeg' || $ext=='tiff') {
  548.         if($exif=mExifArray($completeFilename)) $info['extra']+=$exif;
  549.     }
  550.  
  551.     return $info;
  552. }
  553.  
  554. /**
  555.  * @desc Return audio-file specific info
  556.  *
  557.  * @param string $completeFilename: filename including path
  558.  * @param boolean $getThumbnail: true to include thumbnail
  559.  * @return array
  560.  */
  561. function fiGetInfoAudio($completeFilename,$getThumbnail=false){
  562.     $info=array();
  563.     $ext=cfFileExtension($completeFilename);
  564.  
  565.     // Playlists
  566.     if($ext=='m3u' || $ext=='pls'){
  567.         $nb=0;
  568.         $info['extra']['extraTitle']=array('c'=>cfCaption('explorerAudioPlaylist').cfCaption('genSeparator'));
  569.         $fp=@fopen($completeFilename,'r');
  570.         while (!feof($fp)) {
  571.             if($line=trim(fgets($fp,1024))){
  572.                 // M3U playlist
  573.                 if($ext=='m3u' && substr($line,0,1)!='#'){
  574.                     $info['extra'][++$nb]=array('c'=>($nb).') ','v'=>basename($line));
  575.                 }
  576.                 // Winamp PLS playlist
  577.                 elseif($ext=='pls' && substr($line,0,4)=='File' && strpos($line,'=')){
  578.                     $line=substr($line,strpos($line,'=')+1);
  579.                     $info['extra'][++$nb]=array('c'=>($nb).') ','v'=>basename($line));
  580.                 }
  581.             }
  582.         }
  583.         @fclose($fp);
  584.  
  585.         // Thumbnail
  586.         if($getThumbnail){
  587.             $info['thumbnailURL']='/gfx/fi/big/icoM3U.png';
  588.             $info['thumbnailURLW']=94;
  589.             $info['thumbnailURLH']=120;
  590.             $info['thumbnailNoFrame']=1;
  591.         }
  592.     }
  593.  
  594.     // Audio files
  595.     else{
  596.         $audio=efGetAudioInfo($completeFilename,true);
  597.         foreach ($audio as $key=>$value) if(!strlen($value)) unset($audio[$key]);
  598.  
  599.         $info['extra']['extraTitle']=array('c'=>cfCaption('explorerAudioFileInfo').cfCaption('genSeparator'));
  600.         if(isset($audio['artist'])) $info['extra']['artist']=array('c'=>cfCaption('explorerAudioArtist'),'v'=>$audio['artist']);
  601.         if(isset($audio['album'])) $info['extra']['album']=array('c'=>cfCaption('explorerAudioAlbum'),'v'=>$audio['album']);
  602.         if(isset($audio['track'])) $info['extra']['track']=array('c'=>cfCaption('explorerAudioTrack'),'v'=>$audio['track']);
  603.         if(isset($audio['title'])) $info['extra']['title']=array('c'=>cfCaption('explorerAudioTitle'),'v'=>$audio['title']);
  604.         if(isset($audio['genre'])) $info['extra']['genre']=array('c'=>cfCaption('explorerAudioGenre'),'v'=>$audio['genre']);
  605.         if(isset($audio['year'])) $info['extra']['year']=array('c'=>cfCaption('explorerAudioYear'),'v'=>$audio['year']);
  606.         if(isset($audio['comment'])) $info['extra']['comment']=array('c'=>cfCaption('genComments'),'v'=>$audio['comment']);
  607.  
  608.         // Thumbnail
  609.         if($getThumbnail){
  610.             if(!isset($audio['APIC'])){
  611.                 require_once(INCLUDE_DIR.'explorerFunctions.php');
  612.                 efGetCoverFromFolder($completeFilename,$score);
  613.             }
  614.  
  615.             if(isset($audio['APIC'])||$score>=4){
  616.                 $info['thumbnailURL']=cfExtImage($completeFilename,min($_ENV['thumbnailMaxWidth'],$_ENV['thumbnailMaxHeight']),min($_ENV['thumbnailMaxWidth'],$_ENV['thumbnailMaxHeight']));
  617.                 $info['thumbnailURLW']=min($_ENV['thumbnailMaxWidth'],$_ENV['thumbnailMaxHeight']);
  618.                 $info['thumbnailURLH']=min($_ENV['thumbnailMaxWidth'],$_ENV['thumbnailMaxHeight']);
  619.             }
  620.             else{
  621.                 $info['thumbnailURL']='/gfx/fi/big/icoMus.png';
  622.                 $info['thumbnailURLW']=94;
  623.                 $info['thumbnailURLH']=120;
  624.                 $info['thumbnailNoFrame']=1;
  625.             }
  626.         }
  627.     }
  628.  
  629.     return $info;
  630. }
  631.  
  632. /**
  633.  * @desc Return text file specific info
  634.  *
  635.  * @param string $completeFilename: filename including path
  636.  * @param boolean $getThumbnail: true to include thumbnail
  637.  * @return array
  638.  */
  639. function fiGetInfoVideo($completeFilename,$getThumbnail){
  640.     require_once(INCLUDE_DIR.'viewVideoFunctions.php');
  641.  
  642.     $info=array();
  643.     $ext=cfFileExtension($completeFilename);
  644.     $length=512;
  645.  
  646.     // Video dimensions
  647.     list($width,$height)=vvfVideoDimensions($completeFilename,false);
  648.     if($width) $info['extra']['videoSize'] = array('c'=>cfCaption('genSize'), 'v'=>$width.'x'.$height.' '.cfCaption('genPixels'));
  649.  
  650.     // Video duration
  651.     $duration=vvfVideoDuration($completeFilename);
  652.     $h=floor($duration/3600);
  653.     $m=floor(($duration-3600*$h)/60);
  654.     $s=$duration%60;
  655.     $info['extra']['duration']=array('c'=>cfCaption('explorerAudioTime'),'v'=>str_replace('%3',$s,cfCaption('calHourMinSec',$h,$m)));
  656.  
  657.     // Bitrate
  658.     if($duration>0){
  659.         setlocale(LC_NUMERIC,cfCaption('_ISO_639'));
  660.         $loc=localeconv();
  661.         if(ord($loc['thousands_sep'])==160) $loc['thousands_sep']=' ';
  662.         setlocale(LC_NUMERIC,'eng');
  663.         $info['extra']['br']=array('c'=>cfCaption('genBitrate'),
  664.         number_format(floor(8*cfFileSize($completeFilename)/(1000*$duration)),0,$loc['decimal_point'],$loc['thousands_sep']).
  665.         ' '.cfCaption('explorerKBitPS'));
  666.     }
  667.  
  668.     // Thumbnail
  669.     // Thumbnail URL and size
  670.     if($getThumbnail && cfRGetVar('path') && $width) {
  671.         // Reduce thumbnail size
  672.         if(cfBGetVar('flash')) $_ENV['thumbnailMaxWidth']=120;
  673.  
  674.         // Compute thumbnail width & height
  675.         if($width/$height>$_ENV['thumbnailMaxWidth']/$_ENV['thumbnailMaxHeight'])
  676.             {$info['thumbnailURLW']=$_ENV['thumbnailMaxWidth'];$info['thumbnailURLH']=$_ENV['thumbnailMaxWidth']*$height/$width;}
  677.         else
  678.             {$info['thumbnailURLH']=$_ENV['thumbnailMaxHeight'];$info['thumbnailURLW']=$_ENV['thumbnailMaxHeight']*$width/$height;}
  679.         $info['thumbnailURLW']=floor($info['thumbnailURLW']);
  680.         $info['thumbnailURLH']=floor($info['thumbnailURLH']);
  681.  
  682.         // If browser doesn't support flash, display static screenshot
  683.         if(!cfBGetVar('flash'))
  684.             $info['thumbnailURL']=cfExtVideo($completeFilename,array('image'=>'1','w'=>$info['thumbnailURLW'],'h'=>$info['thumbnailURLH']));
  685.  
  686.         // Else, generate control-less flash player
  687.         else{
  688.             require_once(INCLUDE_DIR.'viewVideoFunctions.php');
  689.             // Player code
  690.             $offset=max(0,min($duration-10,5));
  691.             $offset=0;
  692.  
  693.             // Video URL
  694.             $src=cfExtVideo($completeFilename,array('w'=>$info['thumbnailURLW'],'h'=>$info['thumbnailURLH'],'q'=>'medium','noSound'=>1,'flv'=>1,'offset'=>$offset),'relative','b64');
  695.  
  696.             $info['thumbnailURL']='code:';
  697.             $info['thumbnailURL'].='<object id="playerVideo" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http'.((isset($_SERVER['HTTPS']))?'s':'').'://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="'.$info['thumbnailURLW'].'" height="'.$info['thumbnailURLH'].'" align="middle">';
  698.             $info['thumbnailURL'].='<param name="allowScriptAccess" value="sameDomain" />';
  699.             $info['thumbnailURL'].='<param name="allowFullScreen" value="true" />';
  700.             $info['thumbnailURL'].='<param name="fullScreenRect" value="true" />';
  701.             $info['thumbnailURL'].='<param name="movie" value="'.cfHostName().'/js/vplayer.swf?file='.$src.'&w='.$info['thumbnailURLW'].'&h='.$info['thumbnailURLH'].'&offset='.$offset.'&autoplay=1&buffer=0&browser='.cfGetBrowser().'&noControls=1&loop=1&background=white&bs=5" />';
  702.             $info['thumbnailURL'].='<param name="quality" value="high" />';
  703.             $info['thumbnailURL'].='<param name="bgcolor" value="#000000" />';
  704.             $info['thumbnailURL'].='<embed name="playerVideo" id="playerVideoEmbed" src="'.cfHostName().'/js/vplayer.swf?file='.$src.'&w='.$info['thumbnailURLW'].'&h='.$info['thumbnailURLH'].'&offset='.$offset.'&autoplay=1&buffer=0&browser='.cfGetBrowser().'&noControls=1&loop=1&background=white&bs=5"';
  705.             $info['thumbnailURL'].='swLiveConnect="true"';
  706.             $info['thumbnailURL'].='quality="high"';
  707.             $info['thumbnailURL'].='width="'.$info['thumbnailURLW'].'"';
  708.             $info['thumbnailURL'].='height="'.$info['thumbnailURLH'].'"';
  709.             $info['thumbnailURL'].='allowFullScreen="true"';
  710.             $info['thumbnailURL'].='fullScreenRect="true"';
  711.             $info['thumbnailURL'].='align="middle"';
  712.             $info['thumbnailURL'].='allowScriptAccess="sameDomain"';
  713.             $info['thumbnailURL'].='type="application/x-shockwave-flash"';
  714.             $info['thumbnailURL'].='pluginspage="'.'http'.((isset($_SERVER['HTTPS']))?'s':'').'://www.macromedia.com/go/getflashplayer"';
  715.             $info['thumbnailURL'].='/></object>';
  716.         }
  717.     }
  718.  
  719.     return $info;
  720. }
  721.  
  722. /**
  723.  * @desc Return text file specific info
  724.  *
  725.  * @param string $completeFilename: filename including path
  726.  * @param boolean $getThumbnail: true to include thumbnail
  727.  * @return array
  728.  */
  729. function fiGetInfoText($completeFilename,$getThumbnail){
  730.     $info=array();
  731.     $ext=cfFileExtension($completeFilename);
  732.     $length=512;
  733.  
  734.     // IE URLs
  735.     if($ext=='url'){
  736.         $c=file_get_contents($completeFilename);
  737.         if(stripos($c,'url=')) {
  738.             $c=substr($c,stripos($c,'url=')+4);
  739.             if(strpos($c,"\n")) $c=trim(substr($c,0,strpos($c,"\n")));
  740.             $info['extra'][0]=array('c'=>'URL','vhtml'=>'<a href="#" style="text-decoration:underline">'.$c.'</a>');
  741.         }
  742.     }
  743.  
  744.  
  745.     // Thumbnail
  746.     if($getThumbnail){
  747.         $content='';
  748.         $highlighted=array("c"=>"CPP","cpp"=>"CPP","css"=>"CSS","dtd"=>"DTD","java"=>"JAVA","js"=>"JAVASCRIPT","sql"=>"SQL","mysql"=>"MYSQL","perl"=>"PERL","php"=>"PHP","py"=>"PYTHON","ruby"=>"RUBY","xml"=>"XML","html"=>"XML","htm"=>"XML","opml"=>"XML","vbs"=>"VBSCRIPT","bas"=>"VBSCRIPT","ctl"=>"VBSCRIPT","cls"=>"VBSCRIPT","frm"=>"VBSCRIPT");
  749.  
  750.         // See if content can be coloured
  751.         if(isset($highlighted[$ext])) {
  752.             require_once(INCLUDE_DIR.'Text/Highlighter.php');
  753.  
  754.             // Get head of text file
  755.             $content='';
  756.             if($fp=@fopen($completeFilename,'r')){
  757.                 $lines=0;
  758.                 while (!feof($fp) && strlen($content)<$length && ++$lines<15)
  759.                     $content.=fgets($fp,$length);
  760.                 $all = feof($fp);
  761.                 @fclose($fp);
  762.  
  763.                 $hl = Text_Highlighter::factory($highlighted[cfFileExtension($completeFilename)]);
  764.                 $content=$hl->highlight($content);
  765.                 $content=str_replace("\r","<br>",str_replace("\n","<br>",str_replace("\r\n","<br>",$content)));
  766.                 if(!$all) $content.='<br>...<br>';
  767.             }
  768.         }
  769.  
  770.         // Display as plain text
  771.         else {
  772.             // Get head of text file
  773.             $content='';
  774.             if($fp=@fopen($completeFilename,'r')){
  775.                 $lines=0;
  776.                 while (!feof($fp) && strlen($content)<$length && ++$lines<15)
  777.                     $content.='<br>'.str_replace('<','<',trim(fgets($fp,$length)));
  778.                 if(!feof($fp)) $content.='<br>...<br>';
  779.                 @fclose($fp);
  780.             }
  781.             $content=str_replace(' ',' ',str_replace('    ','    ',$content));
  782.             $content='<div class="hl-main">'.substr($content,4).'</div>';
  783.         }
  784.         $info['thumbnailURL']='code:'.$content;
  785.         /*
  786.         $info['extra']['extraTitle']=array('c'=>cfCaption('genContent').cfCaption('genSeparator'));
  787.         $info['extra']['content']=array('c'=>'','vhtml'=>$content);
  788.         */
  789.     }
  790.  
  791.     return $info;
  792. }
  793.  
  794.  
  795. /**
  796.  * @desc Return archives specific info
  797.  *
  798.  * @param string $completeFilename: filename including path
  799.  * @param boolean $getThumbnail: true to include thumbnail
  800.  * @return array
  801.  */
  802. function fiGetInfoArchive($completeFilename,$getThumbnail){
  803.     $info=array();
  804.     $ext=cfFileExtension($completeFilename);
  805.     $length=512;
  806.  
  807.     $zip = new ZipArchive();
  808.     if(!@$zip->open($completeFilename)) return $info;
  809.  
  810.     // Thumbnail
  811.     if($getThumbnail && $zip->numFiles>0){
  812.         $content='<b>'.cfCaption('genFiles').'</b><br>';
  813.         for($i=0;$i<min($zip->numFiles,10);$i++){
  814.             $content.=($zip->getNameIndex($i)).'<br>';
  815.         }
  816.         if($zip->numFiles>10) $content.='...<br>';
  817.         $info['thumbnailURL']='code:'.$content;
  818.     }
  819.     // ZIP comments
  820.     if($zip->getArchiveComment()){
  821.         $info['extra']['extraTitle']=array('c'=>cfCaption('genComments').cfCaption('genSeparator'));
  822.         $info['extra']['content']=array('c'=>'','v'=>$zip->getArchiveComment());
  823.     }
  824.     $zip->close();
  825.     return $info;
  826. }
  827.  
  828.  
  829. /**
  830.  * @desc Return flash swf specific info
  831.  *
  832.  * @param string $completeFilename: filename including path
  833.  * @param boolean $getThumbnail: true to include thumbnail
  834.  * @return array
  835.  */
  836. function fiGetInfoFlash($completeFilename,$getThumbnail){
  837.     $info=array();
  838.     $ext=cfFileExtension($completeFilename);
  839.     $length=512;
  840.  
  841.     // Thumbnail
  842.     if($getThumbnail){
  843.         $info['thumbnailURL']='code:<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http'.((isset($_SERVER['HTTPS']))?'s':'').'://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="'.$_ENV['thumbnailMaxWidth'].'" height="'.$_ENV['thumbnailMaxHeight'].'">';
  844.     $info['thumbnailURL'].='<param name="movie" value="'.cfExtDownload($completeFilename).'" />';
  845.     $info['thumbnailURL'].='<param name="wmode" value="transparent" />';
  846.     $info['thumbnailURL'].='<embed src="'.cfExtDownload($completeFilename).'" width="'.$_ENV['thumbnailMaxWidth'].'" height="'.$_ENV['thumbnailMaxHeight'].'" type="application/x-shockwave-flash" pluginspage="http'.((isset($_SERVER['HTTPS']))?'s':'').'://www.macromedia.com/go/getflashplayer"    wmode="transparent" /></object>';
  847.     }
  848.     return $info;
  849. }
  850.  
  851. /**
  852.  * @desc Return an array containing file detailled information
  853.  *
  854.  * @param string $completeFilename
  855.  * @return array: (property name => property value)
  856.  */
  857. function fiGetInfo($completeFilename, $getThumbnail=true, $getExtraData=true){
  858.     wSession_write_close();
  859.     if(!file_exists($completeFilename)) return false;
  860.     $ext=cfFileExtension($completeFilename);
  861.  
  862.     // Files with not-text mime type but that should anyway be viewed as text files
  863.     $otherTextExt=array('js'=>1,'bat'=>1);
  864.  
  865.     require_once(INCLUDE_DIR.'explorerFunctions.php');
  866.  
  867.  
  868.  
  869.     /**
  870.      * Common data
  871.      */
  872.  
  873.     // File name
  874.     $info['filename']=basename($completeFilename);
  875.  
  876.     // File size
  877.     if(is_file($completeFilename)) $info['fileSize']=array('c'=>cfCaption('genSize'),'v'=>efFileSizeFormat(cfFileSize($completeFilename)));
  878.  
  879.     // File creation date
  880.     $info['cTime']=array('c'=>cfCaption('dateCTime'),'v'=>date(cfCaption('_FULL_DATE_FORMAT',@filectime($completeFilename))));
  881.  
  882.     // File modification date
  883.     $info['mTime']=array('c'=>cfCaption('dateMTime'),'v'=>date(cfCaption('_FULL_DATE_FORMAT',@filemtime($completeFilename))));
  884.  
  885.     // Icon
  886.     if(is_file($completeFilename)) $info['icon']=efIcon($completeFilename,true);
  887.     else $info['icon']=outIcon('/fi/folder');
  888.  
  889.     // text separator
  890.     $info['sep']=cfCaption('genSeparator');
  891.  
  892.     // Folder specific data
  893.     if(is_dir($completeFilename)) $info+=fiGetInfoFolder($completeFilename,$getThumbnail);
  894.  
  895.     // Image specific data
  896.     elseif(efFileType($completeFilename)=='image') $info+=fiGetInfoImage($completeFilename,$getThumbnail);
  897.  
  898.     // Audio file specific data
  899.     elseif(efFileType($completeFilename)=='audio') $info+=fiGetInfoAudio($completeFilename,$getThumbnail);
  900.  
  901.     // Video file specific data
  902.     elseif(efFileType($completeFilename)=='video') $info+=fiGetInfoVideo($completeFilename,$getThumbnail);
  903.  
  904.     // Text file specific data
  905.     elseif(efFileType($completeFilename)=='text' || !$ext || isset($otherTextExt[$ext])) $info+=fiGetInfoText($completeFilename,$getThumbnail);
  906.  
  907.     // Flash file
  908.     elseif (cfFileExtension($completeFilename)=='swf') $info+=fiGetInfoFlash($completeFilename,$getThumbnail);
  909.  
  910.     // Zip file
  911.     elseif (cfFileExtension($completeFilename)=='zip') $info+=fiGetInfoArchive($completeFilename,$getThumbnail);
  912.  
  913.     // Other file formats : try to get thumbnail
  914.     elseif ($getThumbnail && !cfGGetVar('disableCreateJPG')){
  915.         $res=cfStreamProc('"'.cfAppBinDir().'/createJPG.exe" "'.$completeFilename.'" check 160 160',array('stdout'=>'return'),array('haltOnSeq'=>chr(12)));
  916.         if(substr($res,-1)==chr(12)) $res=substr($res,0,strlen($res)-1);
  917.         if($res!='NOK'){
  918.             @list($ok,$w,$h)=explode(':',$res);
  919.             $info['thumbnailURL']=cfExtImage($completeFilename,$w,$h);
  920.             $info['thumbnailURLW']=$w;
  921.             $info['thumbnailURLH']=$h;
  922.             $info['extra']=array('default'=>array('c'=>'','v'=>' '));
  923.         }
  924.     }
  925.  
  926.     // No extra data...
  927.     if((!isset($info['extra']) || !count($info['extra'])) && !isset($info['thumbnailURL'])) $info['extra']=array('default'=>array('c'=>cfCaption('genNoPreview'),'v'=>' '));
  928.     if(!$getExtraData) unset($info['extra']);
  929.     return $info;
  930. }